<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
		"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
	<title>doh.robot Slider Test</title>

	<style>
		@import "../../../../util/doh/robot/robot.css";
	</style>

	<!-- required: dojo.js -->
	<script type="text/javascript" src="../../../../dojo/dojo.js"></script>

	<script type="text/javascript">
		dojo.require("dijit.robotx");

		// These are all the sliders
		var accessibleSliders = ['slider1','slider2','slider3'];
		var accessibleSliderInit_min = [0.2,10,2,1200];
		var accessibleSliderInit_max = [99.8,90,2,2800];
		var sliderIds = ["slider1", "slider2", "slider3", "sliderH2"];
		var sliderNames = ["horizontal1","vertical1","horizontal2","horizontalH2"];
		var onChange = {slider1: 'slider1input', slider2: 'slider2input'};

		function a11yBoundaryTest(slider, initValue, finalValue){
			// summary:
			//		Sets slider to initValue, which should be either one below the
			//		max, or one above the min.
			//
			//		Use the arrow key once to get to the final value, and
			//		then use the arrow key again (value shouldn't change second time)

			var d = new doh.Deferred();
			var key = initValue < finalValue ? dojo.keys.RIGHT_ARROW : dojo.keys.LEFT_ARROW;

			// Set slider to initial value, one value away from the min or max
			slider.set('value', initValue, false);

			// Focus the slider
			slider.focus();

			// First key press moves to either min or max
			doh.robot.keyPress(key, 500);
			doh.robot.sequence(d.getTestErrback(function(){
				doh.is(Number(finalValue).toFixed(1), Number(slider.get('value')).toFixed(1),
						"value after first " + (key == dojo.keys.RIGHT_ARROW ? "right arrow" : "left arrow"));
				if(onChange[slider.id]){
					doh.is(Number(finalValue).toFixed(1), Number(parseFloat(dojo.byId(onChange[slider.id]).value)).toFixed(1),
						"onchange after first " + (key == dojo.keys.RIGHT_ARROW ? "right arrow" : "left arrow"));
				}

				// Second key press should have no effect, but confirm it
				doh.robot.keyPress(key, 500);
				doh.robot.sequence(d.getTestCallback(function(){
					doh.is(Number(finalValue).toFixed(1), Number(slider.get('value')).toFixed(1),
						"value after second " + (key == dojo.keys.RIGHT_ARROW ? "right arrow" : "left arrow"));
					if(onChange[slider.id]){
						doh.is(Number(finalValue).toFixed(1), Number(parseFloat(dojo.byId(onChange[slider.id]).value)).toFixed(1),
						"onchange after second " + (key == dojo.keys.RIGHT_ARROW ? "right arrow" : "left arrow"));
					}
				}), 500);
			}), 500);
			return d;
		}

		// machinery for testing keyboard manipulation of sliders
		var eaVals = [];	// array holding expected values and actual values after arrow etc. keypresses
		var strokeIndex = 0;
		var noteChanges;

		function keyStrokeSetup(inSliderId){
			// summary:
			//		Populates eaVals[] with expected slider values after each keystroke (in this test),
			//		and sets up listener to record actual value into same eaVals[] array.

			var slider = registry.byId(inSliderId);
			eaVals = populateExpected(slider);
			strokeIndex = 0;
			noteChanges = dojo.global.dojo.connect(slider, "onChange", function(){
				eaVals[strokeIndex++].actual = slider.get('value');
			});
		}

		function populateExpected(/*Slider Widget*/inSlider){
			// summary:
			//		Returns array of expected slider values after each keystroke (in this test)

			var initVal = inSlider.get('value');
			var eVals = [];

			// The values expected by pressing HOME, right arrow five times,
			// PgUp twice, PgDn, up arrow twice, down arrow once,
			// left arrow once, and END.
			inSlider.set('value', inSlider.minimum, false);
			eVals.push({stroke: "HOME", expected: inSlider.get('value')});
			for(var i = 0; i < 5; i++){
				inSlider._bumpValue(1, false);
				eVals.push({stroke: "RIGHT", expected: inSlider.get('value')});
			}
			for(i = 0; i < 2; i++){
				inSlider._bumpValue(inSlider.pageIncrement, false);
				eVals.push({stroke: "PgUp", expected: inSlider.get('value')});
			}
			inSlider._bumpValue(-inSlider.pageIncrement, false);
			eVals.push({stroke: "PgDn", expected: inSlider.get('value')});
			for(i = 0; i < 2; i++){
				inSlider._bumpValue(1, false);
				eVals.push({stroke: "UP", expected: inSlider.get('value')});
			}
			inSlider._bumpValue(-1, false);
			eVals.push({stroke: "DOWN", expected: inSlider.get('value')});
			inSlider._bumpValue(-1, false);
			eVals.push({stroke: "LEFT", expected: inSlider.get('value')});
			inSlider.set('value', inSlider.maximum, false);
			eVals.push({stroke: "END", expected: inSlider.get('value')});

			// reset <inSlider> back to its initial value, and return
			inSlider.set('value', initVal, false);
			return eVals;
		}

		function a11yTabFocusTest(inSliderId){
			var d = new doh.Deferred();
			var slider = registry.byId(inSliderId);
			var focusCount = 0;
			var blurCount = 0;
			var gotFocus = function(){
				focusCount++;
			};
			var lostFocus = function(){
				blurCount++;
			};
			var focusFunc = dojo.global.dojo.connect(slider.focusNode, "onfocus", gotFocus);
			var blurFunc = dojo.global.dojo.connect(slider.focusNode, "onblur", lostFocus);

			// insure a known focus starting point -- the slider to test.
			slider.focus();

			// Shift-tab away, tab to, tab away, shift-tab back.
			doh.robot.keyPress(dojo.keys.TAB, 1000, {
				shift: true
			});
			doh.robot.keyPress(dojo.keys.TAB, 500);
			doh.robot.keyPress(dojo.keys.TAB, 500);
			doh.robot.keyPress(dojo.keys.TAB, 500, {
				shift: true
			});
			var checkGotFocus = function(){
				doh.assertEqual(3, focusCount, slider.id + ": # of times focussed");
				doh.assertEqual(2, blurCount, slider.id + ": # of times lost focus");
				dojo.disconnect(focusFunc);
				dojo.disconnect(blurFunc);
			};
			doh.robot.sequence(d.getTestCallback(checkGotFocus), 1000, 500);
			return d;
		}

		function a11yKeystrokeTest(inSliderId){
			var d = new doh.Deferred();
			var slider = registry.byId(inSliderId);
			var initVal = slider.get('value');
			// get focus on slider thumb before pressing keys.
			slider.focus();
			doh.robot.sequence(function(){
				strokeIndex = 0;
			}, 1000); // insure onChange events have stopped
			doh.robot.keyPress(dojo.keys.HOME, 200);
			doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 1000);
			doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 200);
			doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 200);
			doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 200);
			doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 200);
			doh.robot.keyPress(dojo.keys.PAGE_UP, 200);
			doh.robot.keyPress(dojo.keys.PAGE_UP, 500);
			doh.robot.keyPress(dojo.keys.PAGE_DOWN, 500);
			doh.robot.keyPress(dojo.keys.UP_ARROW, 500);
			doh.robot.keyPress(dojo.keys.UP_ARROW, 200);
			doh.robot.keyPress(dojo.keys.DOWN_ARROW, 200);
			doh.robot.keyPress(dojo.keys.LEFT_ARROW, 200);
			doh.robot.keyPress(dojo.keys.END, 200);
			doh.robot.sequence(d.getTestCallback(function(){
				dojo.disconnect(noteChanges);
				slider.set('value', initVal, false);
				for(var i = 0; i < eaVals.length; i++){
					doh.assertEqual(eaVals[i].expected, eaVals[i].actual, eaVals[i].stroke + " (" + slider.id + ")");
				}
			}), 1000, 500);
			return d;
		}

		dojo.ready(function(){
			doh.robot.initRobot('../test_Slider.html');

			doh.register(function setup(){
				// get pointer to registry in the iframe
				registry = doh.robot.window.require("dijit/registry");
				dfocus = doh.robot.window.require("dijit/focus");
			});

			// TODO: move to Slider.html
			// This tests that Slider is structured so that dojo.query can find the hidden input.
			doh.register("dojo.query() by name",
				function slider1(){
					var slider = registry.byId("slider1"),
						queried = dojo.query("input[name=horizontal1]"),
						bar = slider.valueNode.parentNode,
						barWidth = bar.offsetWidth;
					accessibleSliderInit_min[0] = 100 / (barWidth-1); // discover slider smallest non min value
					accessibleSliderInit_max[0] = 100 - accessibleSliderInit_min[0]; // discover slider largest non max value
					doh.is(1, queried.length, "Expected 1 slider with name horizontal1");
					doh.is(slider.valueNode, queried[0], "Slider's valueNode did not match the one found by dojo.query.");
				}
			);

			// This tests that pressing the arrow keys has no effect on a disabled slider
			// TODO: this doesn't make sense, should just be testing that slider can't get
			// focus.  (And if it doesn't have focus then testing keystrokes is meaningless)
			doh.register("disabledTest",{
				name: accessibleSliders[0]+'_a11y_min',
				slider: accessibleSliders[0],
				timeout: 30000,
				runTest: function(){
					this.slider = registry.byId(this.slider);
					this.slider.set('disabled', true);
					var value = accessibleSliderInit_min[0];
					return a11yBoundaryTest(this.slider, value, value);
				}
			});

			// This tests to make sure that the error keys don't go beyond the min or max values
			doh.register("a11yBoundaryTest - min", {
				name: accessibleSliders[0]+'_a11y_min',
				slider: accessibleSliders[0],
				timeout: 30000,
				runTest: function(){
					this.slider = registry.byId(this.slider);
					this.slider.set('disabled', false);
					return a11yBoundaryTest(this.slider, accessibleSliderInit_min[0], this.slider.minimum);
				}
			});
			doh.register("a11yBoundaryTest",{
				name: accessibleSliders[0]+'_a11y_max',
				slider: accessibleSliders[0],
				timeout: 30000,
				runTest: function(){
					this.slider = registry.byId(this.slider);
					return a11yBoundaryTest(this.slider, accessibleSliderInit_max[0], this.slider.maximum);
				}
			});

			// keyboard a11y tests (robot) -- tab focus
			doh.register("a11yTabFocus",
			[
				{
					name: "slider2TabFocus",
					timeout: 9000,
					runTest: function(){
						return a11yTabFocusTest("slider2");
					}
				},
				{
					name: "slider3TabFocus",
					timeout: 9000,
					runTest: function(){
						return a11yTabFocusTest("slider3");
					}
				}
			]);

			// keyboard a11y tests (robot) -- manipulate slider via keystrokes
			doh.register("a11yKeystrokes", [
				{
					name: "slider1Keystrokes",
					timeout: 9000,
					setUp: function(){
						keyStrokeSetup("slider1");
					},
					runTest: function(){
						return a11yKeystrokeTest("slider1");
					}
				},
				{
					name: "slider2Keystrokes",
					timeout: 9000,
					setUp: function(){
						keyStrokeSetup("slider2");
					},
					runTest: function(){
						return a11yKeystrokeTest("slider2");
					}
				},
				{
					name: "disabledTabStop",
					timeout: 9000,
					runTest: function(){
						var d = new doh.Deferred();

						// focus element after slider 2, and disable slider 2
						doh.robot.window.document.getElementById("slider2input").focus();
						registry.byId("slider2").set("disabled", true);

						// jump to element before slider 2 (hopefully)
						doh.robot.keyPress(dojo.keys.TAB, 1000, {
							shift: true
						});

						doh.robot.sequence(d.getTestCallback(function(){
							doh.is("disableButton", dfocus.curNode.id, "disabled tab stop should be skipped");
						}), 500);
						return d;
					}
				},
				{
					// Check for rounding errors on a fractional slider.
					name: "fractional value",
					timeout: 9000,
					runTest: function(){
						var d = new doh.Deferred();
						var slider = registry.byId("fractionalSlider");
						slider.focus();
						doh.is("0.28", slider.focusNode.getAttribute("aria-valuenow"), "aria-valuenow #0");

						doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500);
						doh.robot.sequence(d.getTestErrback(function(){
							doh.is("0.3", slider.focusNode.getAttribute("aria-valuenow"), "aria-valuenow #1");
							doh.is("0.3", slider.get("value"), "get('value') #1");
							doh.is("0.3", dojo.byId("fractionalSliderInput").value, "value reported in input #1");
						}), 500);

						doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500);
						doh.robot.sequence(d.getTestErrback(function(){
							doh.is("0.28", slider.focusNode.getAttribute("aria-valuenow"), "aria-valuenow #2");
						}), 500);

						doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500);
						doh.robot.sequence(d.getTestCallback(function(){
							doh.is("0.26", slider.focusNode.getAttribute("aria-valuenow"), "aria-valuenow #3");
							doh.is("0.26", slider.get("value"), "get('value') #3");
							doh.is("0.26", dojo.byId("fractionalSliderInput").value, "value reported in input #3");
						}), 500);

						return d;
					}
				}
			]);

			doh.run();
		});
	</script>
</head>
</html>
